home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
os2
/
e33el2.zip
/
emacs
/
19.33
/
lisp
/
sgml-mode.el
< prev
next >
Wrap
Lisp/Scheme
|
1996-07-02
|
42KB
|
1,261 lines
;;; sgml-mode.el --- SGML- and HTML-editing modes
;; Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
;; Author: James Clark <jjc@clark.com>
;; Adapted-By: ESR; Daniel.Pfeiffer@Informatik.START.dbp.de
;; Keywords: wp, hypermedia, comm, languages
;; This file is part of GNU Emacs.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; Configurable major mode for editing document in the SGML standard general
;; markup language. As an example contains a mode for editing the derived
;; HTML hypertext markup language.
;;; Code:
;; As long as Emacs' syntax can't be complemented with predicates to context
;; sensitively confirm the syntax of characters, we have to live with this
;; kludgy kind of tradeoff.
(defvar sgml-specials '(?\" ?-)
"List of characters that have a special meaning for sgml-mode.
This list is used when first loading the sgml-mode library.
The supported characters and potential disadvantages are:
?\\\" Makes \" in text start a string.
?' Makes ' in text start a string.
?- Makes -- in text start a comment.
When only one of ?\\\" or ?' are included, \"'\" or '\"' as it can be found in
DTDs, start a string. To partially avoid this problem this also makes these
self insert as named entities depending on `sgml-quick-keys'. <!----> must
contain an even multiple of two (4, 8, ...) minuses, or Emacs' syntax
mechanism won't recognize a comment.")
(defvar sgml-quick-keys nil
"Use <, >, &, SPC and `sgml-specials' keys ``electrically'' when non-nil.
This takes effect when first loading the library.")
(defvar sgml-mode-map
(let ((map (list 'keymap (make-vector 256 nil)))
(menu-map (make-sparse-keymap "SGML")))
(define-key map "\t" 'indent-relative-maybe)
(define-key map "\C-c\C-i" 'sgml-tags-invisible)
(define-key map "/" 'sgml-slash)
(define-key map "\C-c\C-n" 'sgml-name-char)
(define-key map "\C-c\C-t" 'sgml-tag)
(define-key map "\C-c\C-a" 'sgml-attributes)
(define-key map "\C-c\C-b" 'sgml-skip-tag-backward)
(define-key map [?\C-c left] 'sgml-skip-tag-backward)
(define-key map "\C-c\C-f" 'sgml-skip-tag-forward)
(define-key map [?\C-c right] 'sgml-skip-tag-forward)
(define-key map "\C-c\C-d" 'sgml-delete-tag)
(define-key map "\C-c\^?" 'sgml-delete-tag)
(define-key map "\C-c?" 'sgml-tag-help)
(define-key map "\C-c8" 'sgml-name-8bit-mode)
(define-key map "\C-c\C-v" 'sgml-validate)
(if sgml-quick-keys
(progn
(define-key map "&" 'sgml-name-char)
(define-key map "<" 'sgml-tag)
(define-key map " " 'sgml-auto-attributes)
(define-key map ">" 'sgml-maybe-end-tag)
(if (memq ?\" sgml-specials)
(define-key map "\"" 'sgml-name-self))
(if (memq ?' sgml-specials)
(define-key map "'" 'sgml-name-self))))
(let ((c 127)
(map (nth 1 map)))
(while (< (setq c (1+ c)) 256)
(aset map c 'sgml-maybe-name-self)))
(define-key map [menu-bar sgml] (cons "SGML" menu-map))
(define-key menu-map [sgml-validate] '("Validate" . sgml-validate))
(define-key menu-map [sgml-name-8bit-mode]
'("Toggle 8 Bit Insertion" . sgml-name-8bit-mode))
(define-key menu-map [sgml-tags-invisible]
'("Toggle Tag Visibility" . sgml-tags-invisible))
(define-key menu-map [sgml-tag-help]
'("Describe Tag" . sgml-tag-help))
(define-key menu-map [sgml-delete-tag]
'("Delete Tag" . sgml-delete-tag))
(define-key menu-map [sgml-skip-tag-forward]
'("Forward Tag" . sgml-skip-tag-forward))
(define-key menu-map [sgml-skip-tag-backward]
'("Backward Tag" . sgml-skip-tag-backward))
(define-key menu-map [sgml-attributes]
'("Insert Attributes" . sgml-attributes))
(define-key menu-map [sgml-tag] '("Insert Tag" . sgml-tag))
map)
"Keymap for SGML mode. See also `sgml-specials'.")
(defvar sgml-mode-syntax-table
(let ((table (copy-syntax-table text-mode-syntax-table)))
(modify-syntax-entry ?< "(>" table)
(modify-syntax-entry ?> ")<" table)
(if (memq ?- sgml-specials)
(modify-syntax-entry ?- "_ 1234" table))
(if (memq ?\" sgml-specials)
(modify-syntax-entry ?\" "\"\"" table))
(if (memq ?' sgml-specials)
(modify-syntax-entry ?\' "\"'" table))
table)
"Syntax table used in SGML mode. See also `sgml-specials'.")
(defvar sgml-name-8bit-mode nil
"*When non-`nil' insert 8 bit characters with their names.")
(defvar sgml-char-names
[nil nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
"ensp" "excl" "quot" "num" "dollar" "percnt" "amp" "apos"
"lpar" "rpar" "ast" "plus" "comma" "hyphen" "period" "sol"
nil nil nil nil nil nil nil nil
nil nil "colon" "semi" "lt" "eq" "gt" "quest"
"commat" nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
nil nil nil "lsqb" nil "rsqb" "uarr" "lowbar"
"lsquo" nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
nil nil nil "lcub" "verbar" "rcub" "tilde" nil
nil nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
nil nil nil nil nil nil nil nil
"nbsp" "iexcl" "cent" "pound" "curren" "yen" "brvbar" "sect"
"uml" "copy" "ordf" "laquo" "not" "shy" "reg" "macr"
"ring" "plusmn" "sup2" "sup3" "acute" "micro" "para" "middot"
"cedil" "sup1" "ordm" "raquo" "frac14" "half" "frac34" "iquest"
"Agrave" "Aacute" "Acirc" "Atilde" "Auml" "Aring" "AElig" "Ccedil"
"Egrave" "Eacute" "Ecirc" "Euml" "Igrave" "Iacute" "Icirc" "Iuml"
"ETH" "Ntilde" "Ograve" "Oacute" "Ocirc" "Otilde" "Ouml" nil
"Oslash" "Ugrave" "Uacute" "Ucirc" "Uuml" "Yacute" "THORN" "szlig"
"agrave" "aacute" "acirc" "atilde" "auml" "aring" "aelig" "ccedil"
"egrave" "eacute" "ecirc" "euml" "igrave" "iacute" "icirc" "iuml"
"eth" "ntilde" "ograve" "oacute" "ocirc" "otilde" "ouml" "divide"
"oslash" "ugrave" "uacute" "ucirc" "uuml" "yacute" "thorn" "yuml"]
"Vector of symbolic character names without `&' and `;'.")
;; sgmls is a free SGML parser available from
;; ftp.uu.net:pub/text-processing/sgml
;; Its error messages can be parsed by next-error.
;; The -s option suppresses output.
(defvar sgml-validate-command "sgmls -s"
"*The command to validate an SGML document.
The file name of current buffer file name will be appended to this,
separated by a space.")
(defvar sgml-saved-validate-command nil
"The command last used to validate in this buffer.")
;;; I doubt that null end tags are used much for large elements,
;;; so use a small distance here.
(defconst sgml-slash-distance 1000
"*If non-nil, is the maximum distance to search for matching /.")
(defconst sgml-start-tag-regex
"<[A-Za-z]\\([-.A-Za-z0-9= \n\t]\\|\"[^\"]*\"\\|'[^']*'\\)*"
"Regular expression that matches a non-empty start tag.
Any terminating > or / is not matched.")
(defvar sgml-font-lock-keywords
'(("<\\([!?][a-z0-9]+\\)" 1 font-lock-keyword-face)
("<\\(/?[a-z0-9]+\\)" 1 font-lock-function-name-face)
("[&%][-.A-Za-z0-9]+;?" . font-lock-variable-name-face))
"*Rules for highlighting SGML code. See also `sgml-tag-face-alist'.")
;; internal
(defvar sgml-font-lock-keywords-1 ())
(defvar sgml-face-tag-alist ()
"Alist of face and tag name for faceme